package org.hilo.boot.core.metrics;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer;
import org.springframework.boot.actuate.autoconfigure.metrics.export.influx.InfluxProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import io.micrometer.core.aop.TimedAspect;
import io.micrometer.core.instrument.Clock;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.ipc.http.HttpUrlConnectionSender;
import io.micrometer.influx.InfluxConfig;
import io.micrometer.influx.InfluxMeterRegistry;

/**
 * 
 * @author zollty
 * @since 2022年2月21日
 */
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(InfluxMeterRegistry.class)
@ConditionalOnProperty(prefix = "management.metrics.export.influx", name = "enabled", havingValue = "true", matchIfMissing = true)
@EnableConfigurationProperties(InfluxV2Properties.class)
public class InfluxMetricsExportConfiguration {

    private final InfluxV2Properties properties;

    public InfluxMetricsExportConfiguration(InfluxV2Properties properties) {
        this.properties = properties;
    }

    @Bean
    public InfluxConfig influxConfig() {
        return new InfluxPropertiesConfigDecorator(this.properties);
    }

    @Bean
    public InfluxMeterRegistry influxMeterRegistry(InfluxConfig influxConfig, Clock clock,
            InfluxProperties influxProperties) {
        return InfluxMeterRegistry.builder(influxConfig).clock(clock)
                .httpClient(new HttpUrlConnectionSender(this.properties.getConnectTimeout(),
                        this.properties.getReadTimeout()))
                .build();

    }

    /**
     * Enable @Timed annotation support.
     * 
     * @param registry
     * @return
     */
    @Bean
    public TimedAspect timedAspect(MeterRegistry registry) {
        return new TimedAspect(registry);
    }

    @Bean
    MeterRegistryCustomizer<MeterRegistry> configurer(
            @Value("${spring.application.name}") String applicationName) {
        return registry -> registry.config().commonTags("app", applicationName);
    }

}
